package gtkwire.listener;

import gtkwire.*;
import java.util.Vector;

public class FilteringGTKMessageListener
{
	//--- matchmodes
	public static final int MUST_MATCH_NAME_AND_WIDGET = 0;
	public static final int MUST_MATCH_WIDGET_AND_SIGNAL = 1;
	public static final int MUST_MATCH_ALL = 2;
	public static final int MUST_MATCH_SOMETHING = 3;
	private int matchMode = MUST_MATCH_SOMETHING;

	//--- accept vecs
	private Vector<String> acceptingWidgets = new Vector<String>();
	private Vector<String> acceptingNames = new Vector<String>();
	private Vector<GTKWireSignal> acceptingSignals = new Vector<GTKWireSignal>();

	//--- listener that listens to filtered messages.
 	protected Object listener = null;

	public FilteringGTKMessageListener( Object listener )
	{
		this.listener = listener;
	}

	//--- This is called with incoming messages.
	public void message( GTKWireMessage msg )
	{
		String widget = msg.getWidgetType();
		String name = msg.getWidgetName();
		String signal = msg.getSignal();

		//System.out.println( "FilteringGladeMessageListener w:" + widget + ",n:" + name );
		if( matchMode == MUST_MATCH_NAME_AND_WIDGET )
		{
			boolean v1 = nameAccepted( name );
			boolean v2 = widgetAccepted( widget );
			if( v1 && v2 ) filteredMessage( msg );
		}
		else if( matchMode == MUST_MATCH_WIDGET_AND_SIGNAL )
		{
			boolean v1 = signalAccepted( name );
			boolean v2 = widgetAccepted( widget );
			if( v1 && v2 ) filteredMessage( msg );

		}
		else if( matchMode == MUST_MATCH_ALL )
		{
			boolean v1 = signalAccepted( signal );
			boolean v2 = widgetAccepted( widget );
			boolean v3 = nameAccepted( name );
			if( v1 && v2 && v3 ) filteredMessage( msg );
		}
		else
		{
			if( nameAccepted( name ) )
			{
				filteredMessage( msg );
				return;
			}
			if( widgetAccepted( widget ) )
			{
				filteredMessage( msg );
				return;
			}
			if( signalAccepted( signal ) ) filteredMessage( msg );
		}
	}

	//----------------------------------------------------------- FILTERING	
	public void setMatchMode( int mode ){ matchMode = mode; }

	public void addFilteringWidgetType( String widget ){ acceptingWidgets.add( widget ); }
	public void addFilteringSignal( GTKWireSignal signal ){ acceptingSignals.add( signal ); }
	public void addFilteringName( String name ){ acceptingNames.add( name ); }

	public Vector<GTKWireSignal> getSignals(){ return acceptingSignals; }

	//--- this maybe overloaded for different opp for extending
	public void combine( FilteringGTKMessageListener l )
	{
		Vector<String> addNames = l.getNames();
		//-- duplicates are ok, hit is a hit
		acceptingNames.addAll( addNames );
	}

	private boolean nameAccepted( String name )
	{
		for( String testName : acceptingNames )
			if( testName.equals( name ) ) return true;
		
		return false;
	}

	private boolean widgetAccepted( String widgetType )
	{
		for( String testWidget : acceptingWidgets )
			if( testWidget.equals( widgetType ) ) return true;
		
		return false;
	}

	private boolean signalAccepted( String signal )
	{
		for( GTKWireSignal testSignal : acceptingSignals )
			if( testSignal.isMatch( signal ) ) return true;

		return false;
	}
	
	protected Vector<String> getNames(){ return acceptingNames; }

	//--- Extending use this to handle messages
	public void filteredMessage( GTKWireMessage msg ){}

	//------------------------------------------------------------ LISTENERS
	public void setListener( Object l ){ listener = l; }
	public Object getListener(){ return listener; }

	//------------------------------------------------------------ DEBUG
	public void print()
	{
		for( String testName : acceptingNames )
			System.out.println( "name:" + testName );

		for( String testWidget : acceptingWidgets )
			System.out.println( "widget:" + testWidget );

		for( GTKWireSignal testSignal : acceptingSignals )
			System.out.println( "testSignal:" + testSignal.signalName() );
	}

}//end class